package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.SelectMaps;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.IPage;
import com.itheima.common.context.BaseContext;
import com.itheima.common.result.PageResult;
import com.itheima.common.result.Result;
import com.itheima.dto.IndexPageDTO;
import com.itheima.dto.UserLoginDTO;
import com.itheima.mapper.*;
import com.itheima.pojo.*;
import com.itheima.service.IndexService;
import com.itheima.service.YddUserService;
import com.itheima.util.JwtUtil;
import com.itheima.vo.*;
import io.swagger.models.auth.In;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class IndexServiceImpl implements IndexService {
    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysConfigMapper sysConfigMapper;

    @Autowired
    SysRoleMapper sysRoleMapper;

    @Autowired
    SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    SysMenuMapper sysMenuMapper;

    @Autowired
    SysDictMapper sysDictMapper;

    @Autowired
    YddCateMapper yddCateMapper;

    @Autowired
    YddLinkMapper yddLinkMapper;

    @Autowired
    YddTagMapper yddTagMapper;

    @Autowired
    YddAdvimgMapper yddAdvimgMapper;

    @Autowired
    YddArticleMapper yddArticleMapper;

    @Autowired
    YddUserService yddUserService;

    @Autowired
    YddUserDataMapper yddUserDataMapper;
    @Autowired
    YddUserMapper yddUserMapper;
    @Autowired
    YddAdvposMapper yddAdvposMapper;
   

    /**
     * 登录验证功能
     *
     * @param dto
     * @return
     */
    @Override
    public Result login(UserLoginDTO dto) {
        if (dto.getLoginName().isEmpty()) {
            return Result.error("请输入正确的用户名");
        }
        if (dto.getPassword().isEmpty()) {
            return Result.error("请输入正确的密码");
        }
        QueryWrapper<SysUser> qw = new QueryWrapper<SysUser>();
        String password = DigestUtils.md5DigestAsHex(dto.getPassword().getBytes());
        qw.eq("login_name", dto.getLoginName());
        qw.eq("password", password);
        SysUser sysUser = sysUserMapper.selectOne(qw);
        if (sysUser == null) {
            return Result.error("请输入正确的用户名和密码");
        }
        String token = JwtUtil.getToken(sysUser.getId());
        Map map = new HashMap();
        map.put("token", token);
        return Result.success(map);
    }

    /**
     * 获取系统配置
     *
     * @return
     */
    @Override
    public Result getConfig() {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("tab_value", "system");
        List<SysConfig> list = sysConfigMapper.selectList(qw);
        Map map = new HashMap();
        list.forEach(s -> {
            map.put(s.getAttrKey(), s.getAttrValue());
        });
        return Result.success(map);
    }

    /**
     * 获取用户资料
     *
     * @return
     */
    @Override
    public Result profile() {
        String id = BaseContext.getCurrentId();
        //获取对应用户
        SysUser sysUser = sysUserMapper.selectById(id);
        if (sysUser == null) {
            return Result.error("请输入正确的用户名密码");
        }
        String str = sysUser.getRoleId();
        String[] split = str.substring(1, str.length() - 1).split(",");
        List<String> collects = Arrays.stream(split).map(s -> s.replace("\"", "")).collect(Collectors.toList());

        Set<String> rolemenuIds = new HashSet<>();
        //通过角色获取菜单
        collects.forEach(collect -> {
            SysRole sysRole = sysRoleMapper.selectById(collect);
            QueryWrapper qw = new QueryWrapper();
            qw.eq("role_id", sysRole.getId());

            List<SysRoleMenu> list = sysRoleMenuMapper.selectList(qw);

            List<String> menuIds = list.stream().map(s -> s.getMenuId()).collect(Collectors.toList());
            rolemenuIds.addAll(menuIds);
        });

        LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper();
        lqw.in(SysMenu::getId, rolemenuIds);
        lqw.eq(SysMenu::getType, 1);
        //获取对应菜单对象
        List<SysMenu> menuList = sysMenuMapper.selectList(lqw);

        LambdaQueryWrapper<SysDict> lqw2 = new LambdaQueryWrapper();
        lqw2.select(SysDict::getType);
        lqw2.groupBy(SysDict::getType);
        List<SysDict> sysDicts = sysDictMapper.selectList(lqw2);

        Map DictsMap = new HashMap();
        sysDicts.forEach(s -> {
            LambdaQueryWrapper<SysDict> lqw3 = new LambdaQueryWrapper();
            lqw3.select(SysDict::getValue, SysDict::getLabel);
            lqw3.eq(SysDict::getType, s.getType());
            List<SysDict> Dicts = sysDictMapper.selectList(lqw3);

            Map<String, String> collect = Dicts.stream().collect(Collectors.toMap(SysDict::getValue, SysDict::getLabel));
            DictsMap.put(s.getType(), collect);
        });
        Map map = new HashMap();
        map.put("userInfo", sysUser);
        map.put("menuList", menuList);
        map.put("dictsList", DictsMap);

        return Result.success(map);
    }

    /**
     * 用户端获取首页
     *
     * @return
     */
    @Override
    public Result index() {
        Map map = new HashMap();
        List<YddCate> yddCates = yddCateMapper.selectList(null);
        map.put("allCate", yddCates);
        List<YddLink> yddLinks = yddLinkMapper.selectList(null);
        map.put("allLink", yddLinks);
        List<YddTag> yddTags = yddTagMapper.selectList(null);
        map.put("allTag", yddTags);
        LambdaQueryWrapper<YddAdvimg> lqw1 = new LambdaQueryWrapper();
        lqw1.eq(YddAdvimg::getAdvimgpos, 15);
        List<YddAdvimg> banner = yddAdvimgMapper.selectList(lqw1);
        map.put("banner", banner);
        LambdaQueryWrapper<YddAdvimg> lqw2 = new LambdaQueryWrapper();
        lqw2.in(YddAdvimg::getAdvimgpos, 12, 13);
        List<YddAdvimg> showbanner = yddAdvimgMapper.selectList(lqw2);
        map.put("showBanner", showbanner);
        LambdaQueryWrapper<YddAdvimg> lqw3 = new LambdaQueryWrapper();
        lqw3.eq(YddAdvimg::getAdvimgpos, 14);
        List<YddAdvimg> sideBanner = yddAdvimgMapper.selectList(lqw3);
        map.put("sideBanner", sideBanner);

        Map config = new HashMap();
        List<SysConfig> sysConfigs = sysConfigMapper.selectList(null);
        config.put("allData", sysConfigs);
        LambdaQueryWrapper<SysConfig> lqw4 = new LambdaQueryWrapper();
        lqw4.groupBy(SysConfig::getTabValue);
        lqw4.select(SysConfig::getTabValue);
        List<SysConfig> sysConfigs1 = sysConfigMapper.selectList(lqw4);
        List<ConfigVo> list = new ArrayList<>();
        sysConfigs1.forEach(s -> {
            //获取
            LambdaQueryWrapper<SysConfig> lqw5 = new LambdaQueryWrapper();
            lqw5.eq(SysConfig::getTabValue, s.getTabValue());
            lqw5.groupBy(SysConfig::getGroupValue);
            lqw5.select(SysConfig::getGroupValue);
            List<Map<String, Object>> maps = sysConfigMapper.selectMaps(lqw5);
            ConfigVo configVo = new ConfigVo();
            List<Map> children = new ArrayList<>();
            maps.forEach(s2 -> {
                Map sysConfigs2 = new HashMap();
                String name = String.valueOf(s2.get("group_value"));
                sysConfigs2.put("name", name);
                LambdaQueryWrapper<SysConfig> lqw6 = new LambdaQueryWrapper();
                lqw6.eq(SysConfig::getTabValue, s.getTabValue());
                lqw6.eq(SysConfig::getGroupValue, name);
                List<SysConfig> sysConfigs3 = sysConfigMapper.selectList(lqw6);
                sysConfigs2.put("data", sysConfigs3);
                children.add(sysConfigs2);
            });
            configVo.setChildren(children);
            configVo.setKey(s.getTabValue());
            if (s.getTabValue().equals("system")) {
                configVo.setName("系统设置");
            } else if (s.getTabValue().equals("base")) {
                configVo.setName("基础设置");
            } else {
                configVo.setName("其他设置");
            }
            list.add(configVo);
        });
        config.put("list", list);
        map.put("config", config);
        return Result.success(map);
    }

    /**
     * 获取热门指定文章数据
     *
     * @return
     */
    @Override
    public Result indexNew(Integer page, Integer pagesize) {
        //一天毫秒值
        Long day = System.currentTimeMillis() - 1000 * 60 * 60 * 24L;
        //一周毫秒值
        Long week = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7L;
        IndexNewVo indexNewVo = new IndexNewVo();
        indexNewVo.setDesc("首页大数据");
        //一天之类的数据
        QueryWrapper<YddArticle> dayQw = new QueryWrapper();
        dayQw.between("create_date", day, System.currentTimeMillis());
        dayQw.select("count(*) as count");
        List<Map<String, Object>> maps = yddArticleMapper.selectMaps(dayQw);
        indexNewVo.setNum_day((Long) maps.get(0).get("count"));
        //一周之类的数据
        QueryWrapper<YddArticle> weekQw = new QueryWrapper();
        weekQw.between("create_date", week, System.currentTimeMillis());
        weekQw.select("count(*) as count");
        List<Map<String, Object>> weekCount = yddArticleMapper.selectMaps(weekQw);
        indexNewVo.setNum_week((Long) weekCount.get(0).get("count"));
        //多表分页
        Page<ArticleVo> voPage = new Page<>(page, pagesize);
        yddArticleMapper.pageList(voPage);
        PageResult pageResult = new PageResult();
        pageResult.setCurrenPage(voPage.getCurrent());
        pageResult.setTotalPages(voPage.getPages());
        pageResult.setData(voPage.getRecords());
        pageResult.setPageSize(voPage.getSize());
        pageResult.setCount(voPage.getTotal());
        indexNewVo.setList(pageResult);
        return Result.success(indexNewVo);
    }

    /**
     * 最新的六条数据
     *
     * @return
     */
    @Override
    public Result hot() {
        Page<ArticleVo> voPage = new Page<>(1, 6);
        yddArticleMapper.pageList(voPage);
        Map map = new HashMap();
        map.put("desc", "侧边最新文章");
        map.put("list", voPage.getRecords());
        return Result.success(map);
    }

    /**
     * 侧边推荐文章
     *
     * @return
     */
    @Override
    public Result recommend() {
        List<ArticleVo> recommend = yddArticleMapper.recommend();
        Map map = new HashMap();
        map.put("desc", "侧边最新文章");
        map.put("list", recommend);
        return Result.success(map);
    }

    /**
     * 通过cateid分类获取数据
     *
     * @return
     */
    @Override
    public Result indexList(IndexPageDTO dto) {
        Page<ArticleVo> voPage = new Page<>(dto.getPage(), dto.getLimit());
        yddArticleMapper.indexList(voPage, dto);
        PageResult pageResult = new PageResult();
        pageResult.setCurrenPage(voPage.getCurrent());
        pageResult.setTotalPages(voPage.getPages());
        pageResult.setData(voPage.getRecords());
        pageResult.setPageSize(voPage.getSize());
        pageResult.setCount(voPage.getTotal());
        Map map = new HashMap();
        map.put("list", pageResult);
        return Result.success(map);
    }

    /**
     * 注册
     *
     * @param user
     * @return
     */
    @Override
    public Result reg(YddUser user) {
        QueryWrapper<YddUser> qw = new QueryWrapper<YddUser>();
        String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(password);
        user.setUsername(user.getMobile());
        qw.eq("mobile", user.getMobile());
        YddUser sysUser = yddUserService.getOne(qw);
        if (sysUser != null) {
            return Result.error("用户名已存在");
        }
        yddUserService.save(user);
        String token = JwtUtil.getToken(user.getId().toString());
        Map map = new HashMap();
        map.put("token", token);
        return Result.success(map);
    }

    /**
     * 获取详情
     *
     * @param id
     * @return
     */
    @Override
    public Result show(Integer id) {
        QueryWrapper<YddArticle> qw1 = new QueryWrapper();
        qw1.lt("id", id).select("MAX(id) as id");
        YddArticle prev = yddArticleMapper.selectOne(qw1);
        YddArticle yddArticle2 = new YddArticle();
        if (prev != null) {
            yddArticle2 = yddArticleMapper.selectById(prev.getId());
        }
        QueryWrapper<YddArticle> qw2 = new QueryWrapper();
        qw2.gt("id", id).select("min(id) as id");
        YddArticle next = yddArticleMapper.selectOne(qw2);
        YddArticle yddArticle3 = new YddArticle();
        if (next != null) {
            yddArticle3 = yddArticleMapper.selectById(next.getId());
        }
        Object data = recommend().getData();
        Map map = new HashMap();
        List nextList = new ArrayList();
        nextList.add(yddArticle2);
        List prevList = new ArrayList();
        prevList.add(yddArticle3);
        map.put("next", nextList);
        map.put("prev", prevList);
        map.put("recommend", data);

        YddArticle yddArticle = yddArticleMapper.selectById(id);
        YddArticleVo yddArticleVo = new YddArticleVo();
        BeanUtils.copyProperties(yddArticle, yddArticleVo);
        LambdaQueryWrapper<YddCate> qw3 = new LambdaQueryWrapper();
        qw3.select(YddCate::getCatename);
        qw3.eq(YddCate::getId, yddArticle.getCateid());
        YddCate yddCate = yddCateMapper.selectOne(qw3);
        yddArticleVo.setCatename(yddCate.getCatename());

        String currentId = BaseContext.getCurrentId();
        LambdaQueryWrapper<YddUserData> qw4 = new LambdaQueryWrapper();
        qw4.eq(YddUserData::getUserId, currentId);
        qw4.eq(YddUserData::getArticleId, id);
        List<YddUserData> yddUserData = yddUserDataMapper.selectList(qw4);
        if (yddUserData.size() != 0) {
            yddUserData.forEach(s -> {
                if (s.getType() == 1) {
                    yddArticleVo.setCollect(true);
                } else {
                    yddArticleVo.setLike(true);
                }
            });

        }
        map.put("info", yddArticleVo);
        return Result.success(map);
    }

    /**
     * 主页统计信息
     *
     * @return
     */
    @Override
    public BaseInfoVo baseInfo() {
        //管理员用户数量
        QueryWrapper<SysUser> userLqw = new QueryWrapper<>();
        userLqw.eq("del_flag",0);
        userLqw.select("count(*)");
        List<Map<String, Object>> userNumlist = sysUserMapper.selectMaps(userLqw);
        Long userNum = (Long) userNumlist.get(0).get("count(*)");
        //平台用户注册数量
        QueryWrapper<YddUser> yddUserLqw = new QueryWrapper<>();
        yddUserLqw.select("count(*)");
        List<Map<String, Object>> yddUserNumlist = yddUserMapper.selectMaps(yddUserLqw);
        Long yddUserNum = (Long) yddUserNumlist.get(0).get("count(*)");
        //平台文章总数
        QueryWrapper<YddArticle> articleNumLqw = new QueryWrapper<>();
        articleNumLqw.select("count(*)");
        List<Map<String, Object>> articleNumlist = yddArticleMapper.selectMaps(articleNumLqw);
        Long articleNum = (Long) articleNumlist.get(0).get("count(*)");
        //广告位数量
        QueryWrapper<YddAdvpos> advposNumLqw = new QueryWrapper<>();
        advposNumLqw.select("count(*)");
        List<Map<String, Object>> advposNumlist = yddAdvposMapper.selectMaps(advposNumLqw);
        Long advposNum = (Long) advposNumlist.get(0).get("count(*)");
        //广告图数量
        QueryWrapper<YddAdvimg> advimgNumLqw = new QueryWrapper<>();
        advimgNumLqw.select("count(*)");
        List<Map<String, Object>> advimgNumlist = yddAdvimgMapper.selectMaps(advimgNumLqw);
        Long advimgNum = (Long) advimgNumlist.get(0).get("count(*)");
        //分类数量
        QueryWrapper<YddCate> cateNumLqw = new QueryWrapper<>();
        cateNumLqw.select("count(*)");
        List<Map<String, Object>> cateNumlist = yddCateMapper.selectMaps(cateNumLqw);
        Long cateNum = (Long) cateNumlist.get(0).get("count(*)");
        //标签数量
        QueryWrapper<YddTag> tagNumLqw = new QueryWrapper<>();
        tagNumLqw.select("count(*)");
        List<Map<String, Object>> tagNumlist = yddTagMapper.selectMaps(tagNumLqw);
        Long tagNum = (Long) tagNumlist.get(0).get("count(*)");
        //最新注册新用户
        QueryWrapper<YddUser> yddUsersLqw = new QueryWrapper<>();
        yddUsersLqw.orderByDesc("id");
        Page page = new Page(1,7);
        yddUserMapper.selectPage(page,yddUsersLqw);
        List yddUsers = page.getRecords();
        //点赞文章排行
        List<HotArticleVo> hotArticleVos = yddArticleMapper.hotCount();
        //用户性别分析
        Map userMap = new HashMap();
        QueryWrapper<YddUser> userWomanLqw = new QueryWrapper<>();
        userWomanLqw.eq("sex",1);
        userWomanLqw.select("count(sex)");
        List<Map<String, Object>> womanNum = yddUserMapper.selectMaps(userWomanLqw);
        userMap.put("user_woman",womanNum.get(0).get("count(sex)"));
        QueryWrapper<YddUser> userManLqw = new QueryWrapper<>();
        userManLqw.eq("sex",0);
        userManLqw.select("count(sex)");
        List<Map<String, Object>> manNum = yddUserMapper.selectMaps(userManLqw);
        userMap.put("user_man",manNum.get(0).get("count(sex)"));
        userMap.put("total",yddUserNum);
        //各类型文章发布数量
        List<AllCateVo> voList = yddArticleMapper.cateCount();

        //封装数据
        BaseInfoVo infoVo = BaseInfoVo.builder()
                .admin_num(userNum)
                .all_cate(voList)
                .advimg_num(advimgNum)
                .advpos_num(advposNum)
                .article_num(articleNum)
                .hot_article(hotArticleVos)
                .tag_num(tagNum)
                .new_user(yddUsers)
                .user(userMap)
                .build();

        return infoVo;

    }

}
